package com.lut.edu.apm.payCenter.pay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.lut.edu.apm.commodityCenter.pojo.CommodityOrder;
import com.lut.edu.apm.commodityCenter.service.CommodityOrderService;
import com.lut.edu.apm.payCenter.config.AlipayConfig;
import com.lut.edu.apm.payCenter.pojo.OrderDetail;
import com.lut.edu.apm.payCenter.pojo.SysOrder;
import com.lut.edu.apm.payCenter.pojo.UserOrder;
import com.lut.edu.apm.payCenter.services.OrderDetailService;
import com.lut.edu.apm.payCenter.services.UserOrderService;
import com.lut.edu.apm.payCenter.util.SnowFlake;
import com.lut.edu.apm.webCenter.pojo.UserInfo;
import com.lut.edu.apm.webCenter.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Zhao Suzhen
 * @date `2024/3/28`
 */

@RestController
@RequestMapping("/pay")
public class PayController {

    @Autowired
    UserOrderService userOrderService;

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    OrderDetailService orderDetailService;

    @Autowired
    CommodityOrderService commodityOrderService;

    /**
     * 显示支付宝官方支付页面
     * *
     * * @param sysOrder totalAmount 总金额
     * *                 subject     订单名称
     * *                 auth_code   支付授权码
     * *                 out_trade_no订单编号
     * *                 userId      用户号码
     * *                 commodityOrderList 订单详情
     *
     * @return
     * @throws Exception
     */
    @PostMapping("showPay")
    @ResponseBody
    public String showPay(@RequestBody SysOrder sysOrder) throws Exception {
        Map<String, Object> result;
        if (sysOrder.getTotal_amount() <= 0) {
            return "{\"isSuccess\":401,\"error\":\"金额不能为0\"}";
        }
        if (sysOrder.isAuthCode()) {
            sysOrder.setProduct_code("FACE_TO_FACE_PAYMENT");
            result = barcodePayment(sysOrder);
            saveInfo(sysOrder, 1);
        } else {
            sysOrder.setProduct_code("FAST_INSTANT_TRADE_PAY");
            result = obtainPaymentQRCode(sysOrder);
            saveInfo(sysOrder, 0);
        }
        return JSONObject.toJSONString(result);
    }

    /**
     * 客户收付款支付
     *
     * @param sysOrder
     * @return
     * @throws Exception
     */
    private Map<String, Object> barcodePayment(SysOrder sysOrder) throws Exception {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

        // 构造请求参数以调用接口
        AlipayTradePayRequest request = new AlipayTradePayRequest();
        AlipayTradePayModel model = new AlipayTradePayModel();

        // 设置订单标题
        model.setSubject(sysOrder.getSubject());

        // 设置支付授权码
        model.setAuthCode(sysOrder.getAuth_code());

        // 设置支付场景
        model.setScene("bar_code");

        // 设置商户订单号
        model.setOutTradeNo(String.valueOf(sysOrder.getOut_trade_no()));

        // 设置订单总金额
        model.setTotalAmount(String.format("%.2f", sysOrder.getTotal_amount()));

        // 设置卖家支付宝用户ID
        model.setSellerId(AlipayConfig.seller_id);

        request.setBizModel(model);
        AlipayTradePayResponse response = alipayClient.execute(request);
        String body = response.getBody();
        Object parse = JSONObject.parse(body);
        Map<String, Object> result = new HashMap<>();
        if (response.isSuccess()) {
            result.put("isSuccess", 200);
            result.put("out_trade_no", sysOrder.getOut_trade_no());
            AlipayConfig.logResult(response.getMsg() + "\n order:" + sysOrder);
        } else {
            result.put("isSuccess", 401);
        }
        return result;
    }

    /**
     * 生成二维码，客户扫码支付
     *
     * @param sysOrder
     * @return
     * @throws Exception
     */
    private Map<String, Object> obtainPaymentQRCode(SysOrder sysOrder) throws Exception {
        Map<String, Object> result = new HashMap<>();
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setOutTradeNo(String.valueOf(sysOrder.getOut_trade_no()));
        model.setTotalAmount(String.format("%.2f", sysOrder.getTotal_amount()));
        model.setSubject(sysOrder.getSubject());
        request.setBizModel(model);
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        AlipayConfig.logResult(response.toString() + "\001;\001order:" + sysOrder);
        if (response.isSuccess()) {
            result.put("isSuccess", 200);
            result.put("qr_code", response.getQrCode());
            result.put("out_trade_no", Long.toString(sysOrder.getOut_trade_no()));
        } else {
            result.put("isSuccess", 401);
            result.put("error", response.getSubMsg());
        }
        return result;
    }

    /**
     * 订单信息保存
     * Transactional注解用于事务管理
     *
     * @param sysOrder 系统订单
     * @param status   0：未付款 (扫码支付),
     *                 1：已付款 (收付款支付)
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveInfo(SysOrder sysOrder, int status) {
        UserOrder userOrder = new UserOrder();
        String userId = "";
        if (!"".equals(sysOrder.getUserPhone()) && !sysOrder.getUserPhone().isEmpty()) {
            String userPhone = sysOrder.getUserPhone();
            // 查询用户信息
            UserInfo userInfo = userInfoService.queryInfoByPhone(userPhone);
            if (null != userInfo) {
                userId = String.valueOf(userInfo.getUserId());
                userOrder.setUserId(userId);
                userInfoService.updateUserPoints(userPhone, Math.round(sysOrder.getTotal_amount() * 100));
            } else {
                // 匿名用户
                userId = "X-" + new SnowFlake(0, 0).nextId();
                userOrder.setUserId(userId);
            }
        } else {
            // 匿名用户
            userId = "X-" + new SnowFlake(0, 0).nextId();
            userOrder.setUserId(userId);
        }
        userOrder.setStatus(status);
        userOrder.setOrderNo(String.valueOf(sysOrder.getOut_trade_no()));
        // 获取当前时间
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        userOrder.setGmtCreated(timestamp);
        userOrder.setReFee(Math.round(sysOrder.getTotal_amount() * 100));
        userOrder.setDeFee(Math.round(sysOrder.getDiscount_amount() * 100));
        userOrder.setTotalFee(Math.round(sysOrder.getOrder_amount() * 100));
        userOrder.setAddPoints(Math.round(sysOrder.getTotal_amount() * 100));
        // 保存订单信息
        userOrderService.save(userOrder);
        List<Map<String, Object>> paramList = sysOrder.getOrderDetailsList();
        List<OrderDetail> orderDetailsList = new OrderDetail().init(paramList);
        // 订单详细表
        for (OrderDetail orderDetail : orderDetailsList) {
            orderDetail.setUserId(userId);
            orderDetail.setOrderNo(userOrder.getOrderNo());
            // 更新库存
            commodityOrderService.updateReservePay(orderDetail.getProductId(),
                    orderDetail.getNumber());
        }
        orderDetailService.saveBatch(orderDetailsList);
    }
}

